/*
 * @brief
 * @auther aolei1024@gmail.com
 * @date 2019-12-04
 */
#ifndef _ECHO_SERVER_TEST_H_
#define _ECHO_SERVER_TEST_H_

#include <memory>
#include <boost/asio/io_context.hpp>
#include <boost/asio.hpp>
#include <array>
#include <iostream>
#define BUF_SIZE 1024

using boost::asio::ip::tcp;
class Session :public std::enable_shared_from_this<Session>
{
    public:
        Session(tcp::socket socket):socket_(std::move(socket))
    {
    }
        void Start()
        {
            DoRead();
        }
        void DoRead()
        {
            auto self(shared_from_this());
            socket_.async_read_some(boost::asio::buffer(buff_),
                                    [this,self](boost::system::error_code ec,std::size_t length)
                                    {
                                        if(!ec)
                                        {
                                            DoWrite(length);
                                        }
                                    });
        }
        void DoWrite(std::size_t length)
        {
            auto self(shared_from_this());
            boost::asio::async_write(
                socket_,
                boost::asio::buffer(buff_,length),
                [this,self](boost::system::error_code ec, std::size_t length)
                {
                    if(!ec)
                    {
                        DoRead();
                    }
                });
        }
    private:
        tcp::socket socket_;
        std::array<char,BUF_SIZE> buff_;
};


class Server 
{
    public:
        Server(boost::asio::io_context &ioc,std::uint16_t port)
            :acceptor_(ioc,tcp::endpoint(tcp::v4(),port))
        {
            DoAccept();
        }
        void DoAccept()
        {
            acceptor_.async_accept(
                [this](boost::system::error_code ec,tcp::socket socket)
                {
                    if(!ec)
                    {
                        std::cout<<"Accept "<<socket.remote_endpoint().address().to_string()<<std::endl;
                        std::make_shared<Session>(std::move(socket))->Start();
                    }
                    DoAccept();
                });
        }
    private:
        tcp::acceptor acceptor_;
};


#endif //_ECHO_SERVER_TEST_H_
